package com.netted.operationassistant.activity;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.alibaba.fastjson.JSONObject;
import com.android.volley.VolleyError;
import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.mylhyl.superdialog.SuperDialog;
import com.netted.operationassistant.R;
import com.netted.operationassistant.application.BaseApplication;
import com.netted.operationassistant.constant.Constant;
import com.netted.operationassistant.entity.Port;
import com.netted.operationassistant.http.HttpRequest;
import com.netted.operationassistant.sharedPreferences.SharedPreferencesHelper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android_serialport_api.SerialPort;
import android_serialport_api.SerialPortFinder;

/**
 * Created by lu on 2018/6/22.
 */

public abstract class BaseActivity extends AppCompatActivity {
    SharedPreferencesHelper sharedPreferencesHelper = null;
    protected BaseApplication application;
    protected SerialPort serialPort;
    protected SerialPortFinder serialPortFinder;
    protected OutputStream outputStream;
    private InputStream inputStream;
    private ReadThread mReadThread;
    HttpRequest request = null;
    private boolean serialPortStatus = false; //是否打开串口标志
    public boolean threadStatus = false; //线程状态，为了安全终止线程
    private final String TAG = "SerialPortUtils";

    byte[] sendData = new byte[1024];

    public static String serialValue = "";


    public String catbinetId;
    public String catbinetCode;
    public String catbinetName;
    public String schoolId;
    public String catbinetPortCount;
    public String schoolAreaId;
    public String schoolName;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sharedPreferencesHelper= new SharedPreferencesHelper(this, Constant.XML_NAME);

        catbinetId = sharedPreferencesHelper.getSharedPreference(Constant.XML_CATBINET_ID,"")+"";
        catbinetCode = sharedPreferencesHelper.getSharedPreference(Constant.XML_CATBINET_CODE,"")+"";
        catbinetName = sharedPreferencesHelper.getSharedPreference(Constant.XML_CATBINET_NAME,"")+"";
        schoolId = sharedPreferencesHelper.getSharedPreference(Constant.XML_SCHOOL_ID,"")+"";
        catbinetPortCount = sharedPreferencesHelper.getSharedPreference(Constant.XML_CATBINET_PORT_COUNT,"")+"";
        schoolName = sharedPreferencesHelper.getSharedPreference(Constant.XML_SCHOOL_NAME,"")+"";
        schoolAreaId = sharedPreferencesHelper.getSharedPreference(Constant.XML_SCHOOL_AREA_ID,"")+"";

        BarUtils.setStatusBarVisibility(this,false);
        request = new HttpRequest();


        openSerialPort();

    }

    public String showDevice() {

        serialPortFinder = new SerialPortFinder();
        String[] ds = serialPortFinder.getAllDevices();
        if (ds != null) {
            String res = "";
            for (String d : ds) {
                res += d + "\n";

            }
            LogUtils.e("showDevice= \n" + res);
            ToastUtils.showLong("showDevice= " + res);
            return res;
        } else {
            ToastUtils.showLong("D=========================null");
            LogUtils.e("D=========================null");
        }
        return "";
    }

    /**
     * 关闭串口
     */
    public void closeSerialPort() {
        try {
            inputStream.close();
            outputStream.close();

            this.serialPortStatus = false;
            this.threadStatus = true; //线程状态
            serialPort.close();
        } catch (IOException e) {
            Log.e(TAG, "closeSerialPort: 关闭串口异常：" + e.toString());
            return;
        }
        Log.d(TAG, "closeSerialPort: 关闭串口成功");   //
    }

    private byte[] hex2byte(String hex) {

        String digital = "0123456789ABCDEF";
        String hex1 = hex.replace(" ", "");
        char[] hex2char = hex1.toCharArray();
        byte[] bytes = new byte[hex1.length() / 2];
        byte temp;
        for (int p = 0; p < bytes.length; p++) {
            temp = (byte) (digital.indexOf(hex2char[2 * p]) * 16);
            temp += digital.indexOf(hex2char[2 * p + 1]);
            bytes[p] = (byte) (temp & 0xff);
        }
        return bytes;
    }


    public void  openSerialPort(){
        try {
            application = (BaseApplication)getApplication();
            serialPort = application.getSerialPort();
            outputStream = serialPort.getOutputStream();
            inputStream = serialPort.getInputStream();

            mReadThread = new BaseActivity.ReadThread();
            mReadThread.start();
        } catch (SecurityException e) {
            showDialog("警告","You do not have read/write permission to the serial port.",null);
        } catch (IOException e) {
            showDialog("警告","The serial port can not be opened for an unknown reason.",null);
        } catch (InvalidParameterException e) {
            showDialog("警告","Please configure your serial port first.",null);
        }
    }



    /**
     * 发送串口指令（字符串）
     *
     * @param data String数据指令asdasda
     */
    public void sendSerialPort(String data) {////
        Log.d(TAG, "sendSerialPort: 发送数据");

        try {
            sendData = hex2byte(data);
            if (sendData.length > 0) {
                serialValue = "";
                outputStream.write(sendData);
                Log.d(TAG, "sendSerialPort: 串口数据发送成功:"+data);
            }
        } catch (Exception e) {
            Log.e(TAG, "sendSerialPort: 串口数据发送失败：" + e.toString());
        }

    }


    /**
     * 计算异或值
     * @param data
     * @return
     * @throws Exception
     */
    public static String xor(String data) throws Exception {
        if (StringUtils.isEmpty(data)) {
            throw new Exception("异或运行值不能为空");
        }

        String[] arr = data.split(" ");
        List<Integer> intList = null;

        if (arr.length > 0) {
            intList = new ArrayList<>();
            for (String str : arr) {
                if (str != null && str.length() == 2) {
                    intList.add(Integer.valueOf(str, 16));
                }
            }

            if (intList.size() > 1) {
                int tmp = -1;
                for (int i = 0; i < (intList.size() - 1); i++) {
                    if (-1 == tmp) {
                        tmp = intList.get(0) ^ intList.get(1);
                    } else {
                        tmp = tmp ^ intList.get(i + 1);
                    }
                }
                return Integer.toHexString(tmp).toUpperCase();
            }

        }


        throw new Exception("异或运算条件不足");
    }

    //校验异或值是否正确
    public boolean verify(String data) throws Exception{
        if (StringUtils.isEmpty(data)) {
            throw new Exception("异或运行值不能为空");
        }
        String[] arr = data.split(" ");
        String code = "";
        String str = "";
        for(int i = 0; i < arr.length; i ++){
            if (i > 0 && i < (arr.length - 2)){
                str += arr[i]+" ";
            }

            if(i == (arr.length - 2)){
                code = arr[i];
            }
        }
        String res = xor(str);
        return res.equals(code);
    }

    //打开单个仓口
    public String openPort(String broad,String index){
        if (index.length() == 1){
            index = "0" + index;
        }
        String order = "11 00 02 "+broad+" "+index;
        try{
            String verify = xor(order);
            order = "10 " + order + " " + verify + " 16";
            sendSerialPort(order);

        }catch (Exception e){
            e.printStackTrace();
            LogUtils.e(e.getMessage());
        }

        return order;
    }

    //获取仓口状态
    public Port getPortStatus(String portStr){
        if (StringUtils.isEmpty(portStr)) {
            return null;
        }
        String res = getBroadAndIndexByPort(portStr);
        if (StringUtils.isEmpty(res)) {
            return null;
        }


        String broad = res.split("_")[0];
        String index = res.split("_")[1];

        if (index.length() == 1){
            index = "0" + index;
        }
        String order = "12 00 04 "+broad+" "+index + " 00 00";
        try{
            String verify = xor(order);
            order = "10 " + order + " " + verify + " 16";
            sendSerialPort(order);//"10 12 00 04 00 FF 00 00 E9 16"
            int c = 0;
            while(c < 10){
                if(!"".equals(serialValue) && serialValue.indexOf("10 12 00 04")>-1){
                    break;
                }
                c++;
                Thread.sleep(100);
            }
            if(!"".equals(serialValue) && serialValue.indexOf("10 12 00 04")>-1){
                String[] arr = serialValue.split(" ");
                Port port = new Port();
                port.setBroad(arr[4]);
                port.setIndex(arr[5]);
                port.setIsHas(arr[6].equals("01")?"Y":"N");
                port.setIsOpen(arr[7].equals("00")?"Y":"N");
                serialValue = "";
                return port;
            }else{
                serialValue = "";
            }

        }catch (Exception e){
            e.printStackTrace();
            LogUtils.e(e.getMessage());
        }
        return null;
    }


    /**
     * 查询仓口是否关闭和平板是否进仓 结果16进制转仓口(port)对象
     * @param hex
     * @return
     */
    public Port checkPortResultToPort(String hex) throws Exception {
        if(hex == null){return null;}
        //10 12 00 04 00 00 01 01 16 16
        try{
            if(verify(hex)){
                String[] arr = hex.split(" ");
                Port port = new Port();
                port.setBroad(arr[4]);
                port.setIndex(arr[5]);
                port.setIsHas(arr[6].equals("01")?"Y":"N");
                port.setIsOpen(arr[7].equals("00")?"Y":"N");
                return port;
            }
        }catch (Exception e){
            e.printStackTrace();
            LogUtils.e(e.getMessage());
        }
        return null;

    }


    /**
     * 根据机柜仓口名称获取第几块单片机和对应仓口,为了节省代码,返回结果用下划线分割
     * @param port
     * @return
     */
    public String getBroadAndIndexByPort(String port) {
        if (StringUtils.isEmpty(port)) {
            return null;
        }

        int p = Integer.parseInt(port);
        String broad = "00";
        String index = "00";
        Integer broad_port_0 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "0",-1);
        Integer broad_port_1 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "1",-1);
        Integer broad_port_2 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "2",-1);
        if(broad_port_0 == -1){return null;}
        int t1 = p - broad_port_0;
        if (t1 < 0){
            broad = "00";
            index = Integer.toHexString(p);
        }else{
            if (broad_port_1 > 0){
                int t2 = t1 - broad_port_1;
                if (t2 < 0){
                    broad = "01";
                    index = Integer.toHexString(t1);
                }else{
                    if (broad_port_2 > 0){
                        int t3 = t2 - broad_port_2;
                        if (t3 < 0){
                            broad = "02";
                            index = Integer.toHexString(t2);
                        }else{
                            ToastUtils.showLong("获取数据出错");
                            return null;
                        }
                    }else{
                        ToastUtils.showLong("获取数据出错");
                        return null;
                    }
                }
            }else{
                ToastUtils.showLong("获取数据出错");
                return null;
            }
        }
        return broad+"_"+index;
    }




    //根据仓门位置号码打开仓门
    public void openPort(String port) throws Exception{
        if (StringUtils.isEmpty(port)) {
            return;
        }

        int p = Integer.parseInt(port);
        String broad = "00";

        String index = "00";
        //获取3个电路板的仓门数量,结果等于-1的表示该板不存在
        Integer broad_port_0 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "0",-1);
        Integer broad_port_1 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "1",-1);
        Integer broad_port_2 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "2",-1);
        if(broad_port_0 == -1){return;}
        int t1 = p - broad_port_0;
        if (t1 < 0){
            broad = "00";
            index = Integer.toHexString(p);
        }else{
            if (broad_port_1 > 0){
                int t2 = t1 - broad_port_1;
                if (t2 < 0){
                    broad = "01";
                    index = Integer.toHexString(t1);
                }else{
                    if (broad_port_2 > 0){
                        int t3 = t2 - broad_port_2;
                        if (t3 < 0){
                            broad = "02";
                            index = Integer.toHexString(t2);
                        }else{
                            ToastUtils.showLong("机柜打开仓门出错");
                            throw new Exception("机柜打开仓门出错");
                        }
                    }else{
                        ToastUtils.showLong("机柜打开仓门出错");
                        throw new Exception("机柜打开仓门出错");
                    }
                }
            }else{
                ToastUtils.showLong("机柜打开仓门出错");
                throw new Exception("机柜打开仓门出错");
            }
        }
        openPort(broad,index);
    }

    //根据电路板编号获取该电路板仓门数量
    public void getPortCount(int index){
        try {
            String order = "10 00 02 0"+index+" FF";
            String ver = xor(order);
            order = "10 "+order +" "+ ver + " 16";
            sendSerialPort(order);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    //检测仓门是否全部关闭

    public boolean checkPortIsClose(){
        //获取3个电路板的仓门数量,结果等于-1的表示该板不存在
        final Integer broad_port_0 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "0",-1);
        final Integer broad_port_1 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "1",-1);
        final Integer broad_port_2 = (Integer) sharedPreferencesHelper.getSharedPreference(Constant.XML_BROAD_ + "2",-1);
        try {
            if (broad_port_0 > -1){
                String order = "12 00 04 00 FF 00 00";
                order = "10 " + order + " " + xor(order) + " 16";
                sendSerialPort(order);
                int c = 0;
                while (c < 10){
                    if (!"".equals(serialValue)){
                       break;
                    }
                    c++;
                    Thread.sleep(100);
                }

                if (!"".equals(serialValue)){
                    Constant.checkAllPortIsClose = verifyPortCloseResult(serialValue);
                    serialValue = "";
                }
            }
            if (!Constant.checkAllPortIsClose){
                return Constant.checkAllPortIsClose;
            }
            if (broad_port_1 > -1){
                String order = "12 00 04 01 FF 00 00";
                order = "10 " + order + " " + xor(order) + " 16";
                sendSerialPort(order);
                int c = 0;
                while (c < 10){
                    if (!"".equals(serialValue)){
                        break;
                    }
                    c++;
                    Thread.sleep(100);
                }
                if (!"".equals(serialValue)){
                    Constant.checkAllPortIsClose = verifyPortCloseResult(serialValue);
                    serialValue = "";
                }
            }
            if (!Constant.checkAllPortIsClose){
                return Constant.checkAllPortIsClose;
            }
            if (broad_port_2 > -1){
                String order = "12 00 04 02 FF 00 00";
                order = "10 " + order + " " + xor(order) + " 16";
                sendSerialPort(order);
                int c = 0;
                while (c < 10){
                    if (!"".equals(serialValue)){
                        break;
                    }
                    c++;
                    Thread.sleep(100);
                }
                if (!"".equals(serialValue)){
                    Constant.checkAllPortIsClose = verifyPortCloseResult(serialValue);
                    serialValue = "";
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            LogUtils.e(e.getMessage());
        }

        return Constant.checkAllPortIsClose;
    }

    //解析返回结果,判断该电路板仓门是否全部关闭
    public boolean verifyPortCloseResult(String res){
        serialValue = "";
        if("".equals(res)){
            return false;
        }
        String[] arr = res.split(" ");
        List<String> orders = new ArrayList<>();
//        for(int i = 4; i < arr.length - 2; i ++){        //正式N个仓门专用循环
        for(int i = 4; i < (arr.length - (2 + 8)); i ++){    //演示2个仓门专用循环
            orders.add(arr[i]);
        }
        for(int i = 0; i <= orders.size() - 4; i = i + 4){
            String tips = "第"+orders.get(i)+"块板,第"+orders.get(i+1)+"个仓门,平板入仓状态:"
                    +orders.get(i+2)+",仓门关闭状态:"+orders.get(i+3);
            String status = orders.get(i + 3);
            LogUtils.e(tips);
            boolean b = status.equals("00");
            if (b){//如果仓门是00,表示打开,01表示关闭
                return false;
            }
        }
        serialValue = "";
        return true;
    }


    public void showDialog(String title,String content,SuperDialog.OnClickPositiveListener listener){
        showDialog(title,content,null,listener);
    }

    public void showDialog(String title,String content,String btnName,SuperDialog.OnClickPositiveListener listener){
        new SuperDialog.Builder(this).setRadius(20)
                .setAlpha(1).setCancelable(false)
                .setTitle(title).setMessage(content)
                .setPadding(200,100,200,100)
                .setPositiveButton(btnName==null ?"确定":btnName, listener).build();
    }

    public void showNotarizeDialog(String title,String content,SuperDialog.OnClickPositiveListener positiveListener,SuperDialog.OnClickNegativeListener negativeListener){
        new SuperDialog.Builder(this).setRadius(20)
                .setAlpha(1).setCancelable(false)
                .setTitle(title).setMessage(content)
                .setPadding(200,100,200,100)
                .setPositiveButton("确定", positiveListener)
                .setNegativeButton("取消",negativeListener).build();
    }
    MediaPlayer mediaPlayer = null;
    public void playSound(Context cxt, int resId){
        mediaPlayer = MediaPlayer.create(cxt, resId);
        //设置播放起始点
        mediaPlayer.seekTo(0);
        //开始播放
        mediaPlayer.start();

        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                mediaPlayer.stop();
                mediaPlayer.reset();
            }
        });
    }


    public void stopSound(){
        if (mediaPlayer != null && mediaPlayer.isPlaying()){
            mediaPlayer.stop();
            mediaPlayer.reset();
        }

    }
    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();
            while(!threadStatus) {
                int size;
                try {

                    byte[] buffer = new byte[256];
                    if (inputStream == null) return;
                    size = inputStream.read(buffer);
                    if (size == 0)return;
                    String res = bytesToHexFun(buffer,size*2);
                    if (!"".equals(res)){
                        serialValue = res;
                    }
                    LogUtils.e(size+"=====ReadThread===="+serialValue);
                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }//10 10 00 02 00 04 16 16
            }
        }
    }


    public String bytesToHexFun(byte[] bytes) {
        // 一个byte为8位，可用两个十六进制位标识
        char[] buf = new char[bytes.length * 2];
        int a = 0;
        int index = 0;
        for(byte b : bytes) { // 使用除与取余进行转换
            if(b < 0) {
                a = 256 + b;
            } else {
                a = b;
            }

            buf[index++] = HEX_CHAR[a / 16];
            buf[index++] = HEX_CHAR[a % 16];
        }
        String tmp = new String(buf);
        String s = "";

        for(int i = 0; i < tmp.length() ; i ++){
            if(i % 2 == 0 && i <= (tmp.length()-2)){
                s += tmp.substring(i,i+2)+" ";
            }
        }
        return s;
    }

    public String bytesToHexFun(byte[] bytes,int size) {
        // 一个byte为8位，可用两个十六进制位标识
        char[] buf = new char[bytes.length * 2];
        int a = 0;
        int index = 0;
        for(byte b : bytes) { // 使用除与取余进行转换
            if(b < 0) {
                a = 256 + b;
            } else {
                a = b;
            }

            buf[index++] = HEX_CHAR[a / 16];
            buf[index++] = HEX_CHAR[a % 16];
        }
        String tmp = new String(buf);
        String s = "";

        for(int i = 0; i < tmp.length() && i < size; i ++){
            if(i % 2 == 0 && i <= (tmp.length()-2) && i <= (size-2)){
                s += tmp.substring(i,i+2)+" ";
            }
        }
        return s;
    }
    private final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};




}
